package aiaudio;

import aiaudio.collaborative.CollaborativeAudioTrainingNetwork;
import aiaudio.storage.api.*;
import aiaudio.storage.simple.*;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class AIAudioConsoleApplication {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws TooManyItemsException {
        //100, 500, 1000, 5000, 10000, 50000
        makeTestPack(100);
    }

    protected static void makeTestPack(int artistsCount) throws TooManyItemsException {
        makeTest(10, artistsCount);
        makeTest(50, artistsCount);
        makeTest(100, artistsCount);
        makeTest(500, artistsCount);
        makeTest(1000, artistsCount);
    }

    protected static void makeTest(int usersCount, int artistsCount) throws TooManyItemsException {
        try {
            IAudioTrainingSet trainingSet = generateRandomStorage(usersCount, artistsCount, 2);

            long t1 = Calendar.getInstance().getTimeInMillis();
            CollaborativeAudioTrainingNetwork network = new CollaborativeAudioTrainingNetwork(trainingSet, 1);
            long t2 = Calendar.getInstance().getTimeInMillis();
            network.process();
            long t3 = Calendar.getInstance().getTimeInMillis();
            network.group();
            long t4 = Calendar.getInstance().getTimeInMillis();
            write(artistsCount, usersCount, t2 - t1, t3 - t2, t4 - t3);
        } catch (IOException ex) {
            Logger.getLogger(AIAudioConsoleApplication.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InternalException ex) {
            Logger.getLogger(AIAudioConsoleApplication.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static IAudioTrainingSet generateRandomStorage(int userCount,
            int artistCount, int userGroupCount) throws TooManyItemsException {
        List<IUser> users = new ArrayList<IUser>();
        for (int i = 0; i < userCount; i++) {
            users.add(new User(i + ""));
        }

        List<IArtist> artists = new ArrayList<IArtist>();
        for (int i = 0; i < artistCount; i++) {
            artists.add(new Artist(i + "", "Name" + i));
        }

        Random randomizer = new Random();
        HashMap<IUser, List<Tuple<IArtist, Double>>> ratings =
                new HashMap<IUser, List<Tuple<IArtist, Double>>>();
        for (int i = 0; i < userCount; i++) {
            IUser user = users.get(i);
            ratings.put(user, new Vector<Tuple<IArtist, Double>>() {
            });
            for (int j = 0; j < artistCount; j++) {
                double rating;
                if (i % userGroupCount == j % userGroupCount) {
                    rating = (double) (randomizer.nextInt(2) + 3) / (double) 5;
                } else {
                    rating = (double) (randomizer.nextInt(1) + 0.1) / (double) 5;
                }
                IArtist artist = artists.get(j);
                ratings.get(user).add(new Tuple<IArtist, Double>(artist, rating));
            }
        }

        String storageName = String.format(
                "Storage: users = %d, artists = %d, groups = %d",
                userCount, artistCount, userGroupCount);


        IAudioTrainingSet trainingSet = new AudioTrainingSet(users, artists, ratings);
        return trainingSet;
    }

    private static void write(int countArtist, int usersCount, long initializeTime, long learnTime, long groupTime) throws IOException {
        FileWriter fw = new FileWriter("network.tex", true);
        fw.write(countArtist + "&" + usersCount + "&" + initializeTime + "&" + learnTime + "&" + groupTime + "\\\\ \\hline" + System.getProperty("line.separator"));
        fw.flush();
        fw.close();
    }
}
